package com.lee.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseWrapper<T> implements Serializable {

    private static final long serialVersionUID = -1696727488987157682L;

    @JsonProperty("ret")
    private int code;

    @JsonProperty("msg")
    private List<String> messages = new ArrayList<>();

    @JsonProperty("data")
    private T data;

    public ResponseWrapper() {
    }

    public ResponseWrapper(int code, String message) {
        this.code = code;
        if (message != null) {
            this.messages.add(message);
        }
    }

    public ResponseWrapper(int code, String message, T data) {
        this.code = code;
        if (message != null) {
            this.messages.add(message);
        }
        this.data = data;
    }

    public ResponseWrapper(int code, List<String> message, T data) {
        this.code = code;

        if (message != null) {
            this.messages = message;
        }
        this.data = data;
    }
    public static <T> ResponseWrapperBuilder<T> builder() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> request(HttpServletRequest request) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.request(request);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> ok() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(1).data(null).addMessage("success");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> ok(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(0).data(data).addMessage("success");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> failed(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-1).data(data);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> failed() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-1);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> unlogin() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(2);
        return builder;
    }



    public static <T> ResponseWrapperBuilder<T> exception(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-1).data(data);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> exception() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-1).data(null);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> refused(String realm) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-3).data(null).addMessage(realm + " refused accessing");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> unauthorized(String realm) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(-4).data(null).addMessage(realm + " requires authenticating first");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> validationErrors(Errors errors) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        List<String> errMessages = new ArrayList<>();
        List<ObjectError> errorList = errors.getAllErrors();
        for (int i = 0; i < errorList.size(); i++) {
            errMessages.add(errorList.get(i).getDefaultMessage());
        }
        builder.code(-1).data(null).addMessages(errMessages);
        return builder;
    }

    public static class ResponseWrapperBuilder<T> {
        private int code;
        private List<String> messages = new ArrayList<>();
        private T data;
        private String path;

        public ResponseWrapperBuilder<T> request(HttpServletRequest request) {
            this.path = request.getRequestURI();
            return this;
        }

        public ResponseWrapperBuilder<T> code(int code) {
            this.code = code;
            return this;
        }

        public ResponseWrapperBuilder<T> addMessage(String message) {
            if (null != message)
                this.messages.add(message);
            return this;
        }

        public ResponseWrapperBuilder<T> addMessages(List<String> messages) {
            if (null != messages && !messages.isEmpty()) {
                this.messages.addAll(messages);
            }
            return this;
        }

        public ResponseWrapperBuilder<T> data(T data) {
            this.data = data;
            return this;
        }

        public ResponseWrapper<T> build() {
            return new ResponseWrapper<T>(this.code, this.messages, this.data);
        }
    }
}
